using System;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.ExpressApp.DC;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using System.Collections.Generic;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DomainComponents.Common;
using DevExpress.ExpressApp.Utils;

namespace DomainComponents.XCRM
{
    [DomainComponent]
    [NonPersistent]
    public class QualifyLeadParameters
    {
        public const string LeadQualifyContextId = "LeadQualify";
        public static Type QualifyLeadParametersType = typeof(QualifyLeadParameters);
        public static Type IContactObjectType = typeof(IContact);
        public static Type IAccountObjectType = typeof(IAccount);
        public static QualifyLeadParameters CreateQualifyLeadParameters()
        {
            return (QualifyLeadParameters)ReflectionHelper.CreateObject(QualifyLeadParametersType);
        }

        private static void CopyToCustomer(ILead lead, ICustomer customer)
        {
            customer.Owner = lead.Owner;
            customer.PreferredContactMethod = lead.PreferredContactMethod;
            if (lead is IPhones)
            {
                ((IPhones)lead).CopyTo(customer as IPhones);
            }
            lead.CopyTo(customer as ILeadTarget);
            if (lead is IAddressable)
            {
                ((IAddressable)lead).Copy(customer as IAddressable);
            }
        }

        protected virtual void QualifyCore(ILead lead, IObjectSpace os)
        {
            lead.Status = LeadStatus.Qualified;

            IContact contact = null;
            if (Contact)
            {
                contact = (IContact)os.CreateObject(IContactObjectType);
                CreatedCustomer = contact;

                contact.FirstName = lead.FirstName;
                contact.LastName = lead.LastName;
                CopyToCustomer(lead, contact);
            }
            if (Account)
            {
                IAccount account = (IAccount)os.CreateObject(IAccountObjectType);
                CreatedCustomer = account;

                account.AccountName = lead.CompanyName;
                account.SICCode = lead.SICCode;
                account.NumberOfEmployees = lead.NumberOfEmployees;
                account.WebSite = lead.WebSite;
                if (lead is IGenericEmail)
                {
                    ((IGenericEmail)lead).Copy(account as IGenericEmail);
                }

                if (Contact)
                {
                    account.Contacts.Add(contact);
                    account.PrimaryContact = contact;
                }
                CopyToCustomer(lead, account);
            }
        }

        protected virtual void QualifyCompleted(ILead lead, IObjectSpace os)
        {
            CreatedCustomer = (ICustomer)os.GetObject(CreatedCustomer);
        }

        public QualifyLeadParameters()
        {
        }

        public void Qualify(ILead lead, IObjectSpace os)
        {
            Guard.CheckObjectFromObjectSpace(os, lead);
            Validator.RuleSet.Validate(os, this, LeadQualifyContextId);

            using (IObjectSpace nos = os.CreateNestedObjectSpace())
            {
                lead = nos.GetObject<ILead>(lead);
                QualifyCore(lead, nos);
                nos.CommitChanges();
                QualifyCompleted(lead, os);
            }
        }

        public bool Account { get; set; }
        public bool Contact { get; set; }

        [RuleFromBoolProperty("IsAccountOrContactSelected", LeadQualifyContextId, "You should select Contact or/and Account",
            UsedProperties = "Account,Contact")]
        [System.ComponentModel.Browsable(false)]
        public bool IsAccountOrContactSelected
        {
            get
            {
                return this.Account || this.Contact;
            }
        }

        [System.ComponentModel.Browsable(false)]
        public ICustomer CreatedCustomer { get; private set; }
    }


    [DomainComponent]
    [NonPersistent]
    public class QualifyLeadParametersWithOpportunity : QualifyLeadParameters
    {
        public static Type IOpportunityObjectType = typeof(IOpportunity);
        public bool Opportunity { get; set; }
        protected override void QualifyCore(ILead lead, IObjectSpace os)
        {
            base.QualifyCore(lead, os);
            if (Opportunity)
            {
                IOpportunity opportunity = (IOpportunity)os.CreateObject(IOpportunityObjectType);
                opportunity.PotentialCustomer = CreatedCustomer;
                opportunity.Name = lead.Topic;
                lead.CopyTo(opportunity as ILeadTarget);
            }
        }
    }

    //[DefaultClassOptions]
    ////[ImageName("BO_Contact")]
    ////[DefaultProperty("DisplayMemberNameForLookupEditorsOfThisType")]
    ////[DefaultListViewOptions(MasterDetailMode.ListViewOnly, false, NewItemRowPosition.None)]
    ////[Persistent("DatabaseTableName")]
    //// Specify more UI options using a declarative approach (http://documentation.devexpress.com/#Xaf/CustomDocument2701).
    //public class ILead_Qulify : BaseObject
    //{ // Inherit from a different class to provide a custom primary key, concurrency and deletion behavior, etc. (http://documentation.devexpress.com/#Xaf/CustomDocument3146).
    //    public ILead_Qulify(Session session)
    //        : base(session)
    //    {
    //    }
    //    public override void AfterConstruction()
    //    {
    //        base.AfterConstruction();
    //        // Place your initialization code here (http://documentation.devexpress.com/#Xaf/CustomDocument2834).
    //    }
    //    //private string _PersistentProperty;
    //    //[XafDisplayName("My display name"), ToolTip("My hint message")]
    //    //[ModelDefault("EditMask", "(000)-00"), Index(0), VisibleInListView(false)]
    //    //[Persistent("DatabaseColumnName"), RuleRequiredField(DefaultContexts.Save)]
    //    //public string PersistentProperty {
    //    //    get { return _PersistentProperty; }
    //    //    set { SetPropertyValue("PersistentProperty", ref _PersistentProperty, value); }
    //    //}

    //    //[Action(Caption = "My UI Action", ConfirmationMessage = "Are you sure?", ImageName = "Attention", AutoCommit = true)]
    //    //public void ActionMethod() {
    //    //    // Trigger a custom business logic for the current record in the UI (http://documentation.devexpress.com/#Xaf/CustomDocument2619).
    //    //    this.PersistentProperty = "Paid";
    //    //}
    //}
}
